<template>
  <div class="image-upload">
    <el-upload v-show="!fileUrl && !disabled"
               ref="uploadImageRef"
               drag
               action="#"
               :auto-upload="false"
               :show-file-list="false"
               :accept="accept"
               :on-change="getFile"
               :limit="1">
      <template #trigger>
        <i class="el-icon-upload"></i>
        <div class="el-upload-text">拖拽/点击上传</div>
      </template>
    </el-upload>
    <div class="uploaded " :class="{'uploaded-big-img' : isbig}"
         v-show="fileUrl || disabled">
      <el-image :class="['uploaded-img', {'is-empty': !fileUrl}]"
                :src="fileUrl"
                :preview-src-list="[fileUrl]">
        <div slot="error"
             class="image-slot">
          <i class="el-icon-picture-outline"></i>
        </div>
      </el-image>
      <div v-if="!disabled"
           class="clear-icon"
           @click="handleClear">
        <i class="el-icon-error"></i>
      </div>
    </div>
    <div v-show="uploadTips && uploadStatus"
         class="upload-tips"
         :style="tipsStyle">
      <div class="upload-progress"
           :style="`width: ${progress}%`"></div>
      <div class="text">{{uploadTips}}</div>
    </div>
  </div>
</template>

<script>
export default {
  name: "ImageUpload",
  model: {
    prop: 'fileUrl',
    event: 'fileUrl'
  },
  props: {
    isbig:{
      type:Boolean,
      default:false
    },
    // 图片类型
    accept: {
      type: String,
      default: ".jpg,.jpeg,.png"
    },
    // 图片大小，单位：
    fileSize: {
      type: Number,
      default: 10
    },
    // 图片路径
    fileUrl: {
      type: String,
      default: ""
    },
    // 图片比例 宽*高
    fileScale: {
      type: String,
      default: ""
    },
    // 禁止上传
    disabled: {
      type: Boolean,
      default: false
    },
    // 上传进度
    progress: {
      type: [Number, String],
    },
    // 用于修改表单的校验规则
    rules: {
      type: Array | Object,
      default: () => []
    }
  },
  data () {
    return {
      file: {},
      fileType: "",
      uploadTips: "",
      uploadStatus: "",
    };
  },
  computed: {
    tipsStyle () {
      if (this.uploadStatus === "error") {
        return {
          background: "#ff385466",
        };
      } else if (this.uploadStatus === "success") {
        return {
          background: "#57A333"
        };
      } else if (this.uploadStatus === "progress") {
        return {
          background: "#18181866",
        };
      } else {
        return {};
      }
    }
  },
  watch: {
    progress (val) {
      if (this.progress >= 0) {
        this.uploadTips = val + '%';
        this.uploadStatus = "progress";
      }
    },
    fileUrl: {
      handler (newVal) {
        if (!newVal) {
          this.uploadTips = "";
          this.uploadStatus = "";
        }
      },
      immediate: true,
      deep: true
    },
  },
  mounted () {
    this.setRules()
    // console.log('isbig',this.isbig);
  },
  methods: {
    setRules () {
      let validator = async (rule, value, callback) => {
        if (!this.validateImageType()) return callback(new Error(`请上传${this.accept}格式的图片`));
        if (!(await this.validateFileScale())) return callback(new Error(`请上传${this.fileScale}比例的图片`));
      }
      this.$emit("update:rules", [
        ...this.rules,
        { validator: validator, trigger: 'change' }
      ])
    },
    validateImageType () {
      let fileType = this.file?.type
      let allowedTypes = this.accept.split(",");
      allowedTypes = allowedTypes.map(item => item.split(".")[1]);
      const result = fileType ? allowedTypes.includes(
        fileType.toLowerCase().split("/")[1]
      ) : 1;
      if (!result) {
        this.uploadTips = "格式不符";
        this.uploadStatus = "error";
      }
      return result;
    },
    validateFileSize (fileSize) {
      if (fileSize / 1024 / 1024 > this.fileSize) {
        this.uploadTips = "文件过大";
        this.uploadStatus = "error";
        return;
      };
    },
    validateFileScale () {
      if (this.fileScale) {
        return new Promise((resolve, reject) => {
          let img = new Image();
          img.src = URL.createObjectURL(this.file);
          img.onload = () => {
            const width = this.fileScale.split('*')[0];
            const height = this.fileScale.split('*')[1];
            const rate = width / height;
            const size = img.naturalWidth / img.naturalHeight;
            size === rate ? resolve(true) : reject(false);
          }
        }).then(
          () => { return true; },
          () => {
            this.uploadTips = "格式不符";
            this.uploadStatus = "error";
            return false;
          }
        )
      } else {
        return true
      }
    },
    async getFile (file) {
      this.file = file.raw;
      this.$emit("fileUrl", URL.createObjectURL(file.raw));
      if (!this.validateImageType()) return;
      if (!(await this.validateFileScale())) return;
      // if (!this.validateFileSize(file.raw.size)) return;
      this.$emit("change", file);
    },
    handleClear () {
      this.$refs.uploadImageRef.clearFiles();
      this.file = {};
      this.$emit("fileUrl", "");
      this.$emit("change", null);
    }
  }
};
</script>

<style lang="scss" scoped>
.image-upload {
  position: relative;
  width: 84px;
  height: 80px;
  
  display: inline-block;
  // 图片上传区域
  :deep(.el-upload-dragger) {
    width: 84px;
    height: 80px;
    border-radius: 4px;
    border: 1px dashed #E1E2E6;
    background: #F6F6F6;
    .el-icon-upload {
      margin: 6px 0 0;
      font-size: 30px;
      color: #cbcbcb;
    }
    .el-upload-text {
      font-size: 12px;
      color: #B9B9B9;
      line-height: 17px;
    }
    &:hover {
      border-color: #C0C4CC;
    }
  }
  // 已上
  .uploaded {
    position: relative;
    .uploaded-img {
      width: 84px;
      height:80px;
      background: #00000033;
      border-radius: 4px;
      &.is-empty {
        background: #F6F6F6;
        display: flex;
        justify-content: center;
        align-items: center;
        border: 1px solid #E1E2E6;
        color: #cbcbcb;
        border-radius: 4px;
        .el-icon-picture-outline {
          font-size: 22px;
          transform: scaleX(1.2);
        }
      }
      .image-slot {
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
  
    :deep(.clear-icon) {
      position: absolute;
      font-size: 16px;
      color: #57A333;
      top: -16px;
      right: -8px;
      cursor: pointer;
      .el-icon-error::before {
        position: relative;
        z-index: 1;
      }
      .el-icon-error::after {
        content: '';
        position: absolute;
        right: 5px;
        top: 8px;
        width: 6px;
        height: 6px;
        background: #fff;
        z-index: 0;
      }
      &:hover {
        color: #79b55c;
      }
    }
  }
  //区分上传楼盘图片、电梯图片情况
  .uploaded-big-img{
    .uploaded-img{
      width: 200px !important;
      height: 220px !important;
          }
          :deep(.clear-icon) {
            right: -140px !important;
          }
  }
  // 上传提示
  .upload-tips {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    font-size: 11px;
    color: #ffffff;
    line-height: 20px;
    height: 20px;
    text-align: center;
    border-radius: 0 0 4px 4px;
    overflow: hidden;
    .upload-progress {
      position: absolute;
      height: 100%;
      background: #57A333;
    }
    .text {
      position: relative;
      z-index: 2;
    }
  }
}
</style>